package com.markerhub.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.markerhub.entity.SysMenu;
import com.markerhub.entity.SysRole;
import com.markerhub.entity.SysUser;
import com.markerhub.mapper.SysUserMapper;
import com.markerhub.service.SysMenuService;
import com.markerhub.service.SysRoleService;
import com.markerhub.service.SysUserService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.markerhub.utils.RedisUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.logging.Logger;
import java.util.stream.Collectors;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author 倪圳褒
 * @since 2024-01-25
 */
@Service
@Slf4j
public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> implements SysUserService {

    @Autowired
    RedisUtil redisUtil;
    @Autowired
    SysRoleService sysRoleService;
    @Autowired
    SysUserMapper sysUserMapper;
    @Autowired
    SysMenuService sysMenuService;

    @Override
    public SysUser getByUsername(String username) {
        return getOne(new QueryWrapper<SysUser>().eq("username", username));
    }

    @Override
    public void clearUserAuthorityInfo(String username) {
        redisUtil.hdel("GrantedAuthority:"+username);
    }

    @Override
    public String getUserAuthorityInfo(Long userId) {
        SysUser sysUser = this.getById(userId);
        String authority = null;

        if (redisUtil.hasKey("GrantedAuthority:" + sysUser.getUsername())) {
            // 优先从缓存获取
            authority = (String)redisUtil.get("GrantedAuthority:" + sysUser.getUsername());

        } else {

            List<SysRole> roles = sysRoleService.list(new QueryWrapper<SysRole>()
                    .inSql("id", "select role_id from sys_user_role where user_id = " + userId));
            List<Long> menuIds = sysUserMapper.getNavMenuIds(userId);
            List<SysMenu> menus = sysMenuService.listByIds(menuIds);

            String roleNames = roles.stream().map(r -> "ROLE_" + r.getCode()).collect(Collectors.joining(","));
            String permNames = menus.stream().map(m -> m.getPerms()).collect(Collectors.joining(","));

            authority = roleNames.concat(",").concat(permNames);
            log.info("用户ID - {} ---拥有的权限：{}", userId, authority);

            redisUtil.set("GrantedAuthority:" + sysUser.getUsername(), authority, 60*60);

        }
        return authority;
    }

    @Override
    public void clearUserAuthorityInfoByRoleId(Long roleId) {
        List<SysUser>sysUsers= this.list(new QueryWrapper<SysUser>().
                inSql("id","select user_id from sys_user_role where role_id="+roleId));
        sysUsers.forEach(u->{
            this.clearUserAuthorityInfo(u.getUsername());
        });

    }

    @Override
    public void clearUserAuthorityInfoByMenuId(Long menuId) {
        List<SysUser>sysUsers=sysUserMapper.listByMenuId(menuId);
        sysUsers.forEach(u->{
            this.clearUserAuthorityInfo(u.getUsername());
        });
    }
}
